#include "./wtime.h"

#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>


void mds_wtime_init( mds_wtime *wtime )
{
	LARGE_INTEGER li;
	assert( wtime );
    (void) QueryPerformanceFrequency(&li);
    wtime->freq = 1.0/( (double)(li.QuadPart) );
}

void mds_wtime_start( mds_wtime *wtime )
{
	LARGE_INTEGER li;
	assert( wtime );
    QueryPerformanceCounter(&li);
    wtime->quad = li.QuadPart;
}


double mds_wtime_query( mds_wtime *wtime )
{
    LARGE_INTEGER li;
	assert( wtime );
    QueryPerformanceCounter(&li);
    return ( (double)(li.QuadPart - wtime->quad) )* wtime->freq;
}

int64_t mds_wtime_ticks(void)
{
	LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
	return li.QuadPart;
}


#else

#include <stdlib.h>
#include <sys/time.h>

void mds_wtime_init( mds_wtime *wtime )
{
#if defined(__INTEL_COMPILER)
#	pragma warning ( disable : 869 )
#endif
	assert( wtime );
}

void   mds_wtime_start( mds_wtime *wtime )
{
	struct timeval *tv = (struct timeval *) wtime;
	assert( wtime != NULL );
	(void) gettimeofday( tv, NULL );
}

double mds_wtime_query( mds_wtime *wtime )
{
	struct timeval now;
    (void) gettimeofday( &now, NULL);
	{
		
		struct timeval *old = (struct timeval *) wtime;
		const double nsec = (now.tv_sec  > old->tv_sec  ) ? (double)( now.tv_sec  - old->tv_sec  ) : - (double)( old->tv_sec  - now.tv_sec  );
		const double usec = (now.tv_usec > old->tv_usec ) ? (double)( now.tv_usec - old->tv_usec ) : - (double)( old->tv_usec - now.tv_usec );
		return nsec + 1.0e-6 * usec;
	}
}

int64_t mds_wtime_ticks(void)
{
	static const int64_t oneM = 1000000;
	struct timeval now;
    (void) gettimeofday( &now, NULL);
	{
		const int64_t nsec  = now.tv_sec;
		const int64_t nusec = now.tv_usec;
		return oneM * nsec + nusec;
	}
}

#include <math.h>

void mds_eta_compute( mds_eta *eta, double s )
{
	assert(eta);
	eta->d = floor( s/86400.0 );
	s -= eta->d * 86400;
	eta->h = floor(s/3600.0);
	s -= eta->h * 3600.0;
	eta->m = floor(s/60.0);
	eta->s = s - (60.0*eta->m);
}


#endif
